<?php

namespace App\Console\Commands;


use Illuminate\Console\Command;


class File extends Command
{
    /**
     * File 文件锁
     *
     * 请求：
     *  php artisan command:file
     *  sudo -u www php /www/wwwroot/slh/laravel.test/artisan command:file
     *  sudo -u www php /www/wwwroot/shenlanhui/laravel/artisan command:file
     *
     */
    /**
     * 参数与选项的区别
     *      在执行命令时，参数必须严格按定义时的顺序输入，不需输入参数名，只需输入参数的值即可。
     *      输入选项则必须带选项名，且选项名前须加 -- 前缀（选项简写字母前加 -），选项可按任意顺序输入
     */

    // 请求 以及参数
    // protected $signature = 'command:name {param1} {param2}';  // 必填参数
    // protected $signature = 'command:name {参数名?} {参数名=默认值} {参数名? : 参数说明}';  // 可选参数
    // protected $signature = 'command:name {--选项名} {--选项名=} {--选项名=默认值} {--简写字母|选项名} {--选项名 : 选项说明}';  // 选项
    protected $signature = 'command:file';


    protected $description = '文件锁：同时执行多个的时候，只有一个能操作';

    public function __construct()
    {
        parent::__construct();
    }

    // 参数与选项
    public function handle()
    {
        $file = app()->basePath().DIRECTORY_SEPARATOR.'example.txt';

        // 获取内容
        //  在修改中，获取到的内容是空的
        $data = file_get_contents($file);
        $this->line('=====展示内容开始=====');
        $this->line($data);
        $this->line('=====展示内容结束=====');

        // 获取内容
        //  在修改中，获取到的内容是空的
        $fopen = fopen($file, 'r');
        $data = fread($fopen, filesize($file));
        fclose($fopen);
        $this->line('=====展示内容开始=====');
        $this->line($data);
        $this->line('=====展示内容结束=====');

        // 打开文件
        $res = $this->file_put_data($file, '需要添加的倒文件中的内容'.chr(10));
        if(is_string($res)){
            $this->error($res);
        }

        return $this->info('操作完成！！');
    }

    // 文件操作
    protected function file_put_data($file, $data)
    {
        $fp = fopen($file, 'a+');
        if(!$fp){
            return '文件不存在';
        }

        // 尝试获取独占锁
        if(flock($fp, LOCK_EX)){  // 获得了锁
            // 在这个区域内，文件是被锁定的，其他进程不能修改
            // 如果其他地方需要修改 只能等这个修改结束后才能修改
            fwrite($fp, $data);

            for($ii = 0; $ii < 10; $ii++){
                $this->line($ii);
                sleep(1);
            }


            // 解锁
            flock($fp, LOCK_UN);
        } else{
            // 无法获得锁
            return '打开文件失败';
        }
        // 关闭文件
        fclose($fp);

        return true;
    }

}
